
(in-package :toygen)

(defparameter *seq0*
  '(module "main.c"
    (include :global t "stdio.h")
    (func int main (int argc (ptr (const char)) argv)
     :comment "defines entry point to the console application"
     :body
     (fputs "Hello, world" stderr)
     (return 0)
     )
    ))

(defparameter *mappings* (make-hash-table))

(defmacro add-mapping (symbol function)
  `(progn
    (unless (symbolp ,symbol) (error "mapping symbol is missing"))
    (unless (typep ,function 'function) (error "function is missing"))
    (if (gethash ,symbol *mappings*)
	(error "symbol is already defined"))
    (setf (gethash ,symbol *mappings*) ,function))
  )

(defun process-ast-list (ast-context ast-list)
  (let ((func-s      ;(format t "ast-handler(~a: args = )" ,args)
ym (first ast-list)) ast-handler ast-call)
    (setf ast-handler (gethash func-sym *mappings*))
    (setf ast-call (list 'funcall ast-handler ast-context))
    (unless ast-handler (error "ast-handler is nil"))
    (append ast-call (cdr ast-list))
    (eval ast-call)
    ))

(defmacro def-ast-handler (ast-name args body)
  `(add-mapping ',ast-name (lambda ,args ,body))
  )

(def-ast-handler test (ast-context name)
  (format t "ast-handler-test (~a ~a)~%" ast-context name)
  )

;(add-mapping test )

#|(defun ast-handler-func (ast-context
			 type ast-name args
			 &key
			 ((:gen-name gen-name) ast-name)
			 ((:modifier modifier) nil)
			 ((:comment comment) nil)
			 ((:body body) nil))
  )|#

(defun test-seq0 ()
  (process-ast-list 778 '(test "test.c"))
  )

(defparameter *seq1*
  '(func int main ((int argc) (const-char-pp argv))
     (return 0)
     )
  ) ; defparameter *seq1*

(defun toy-eval (site element)
  (if (listp element)
    (let ((func-name (car element)) (args (cdr element)) prep-token)
      (setf prep-token (pre-process-function site func-name args))

      (dolist (a args)
        (toy-eval site a)
        )

      (post-process-function site func-name args prep-token)
      )
    ; else
    (process-atom site element)
    )
  )

;====
;
(defun test3 ()
  (test-seq0)
  (format t "~%---~%~%")

  (if nil
      (let ((site (make-instance 'Sample1EvaluatorSite)))
    (toy-eval site '(a b 12 14 (emb-a emb-b 123) c))
    ))
  )